﻿using JGSY.SerialCommunication.UpperComputer.Component;
using JGSY.SerialCommunication.UpperComputer.Core;
using JGSY.SerialCommunication.UpperComputer.Core.EnumType;
using JGSY.SerialCommunication.UpperComputer.IComponent;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JGSY.SerialCommunication.UpperComputer.Modbus
{
    public class ModbusTcp : ModbusBase
    {
        public override bool IsModbusTcp { get { return true; } }
       
        private ModbusTcp()
        {
        }
        public ModbusTcp(string ipAddress, int port, int timeout = 1000)
        {
            CommunicationUnit = new Ethernet(ipAddress, port, timeout, timeout, ProtocolType.Tcp);
        }

     
        public override byte[] SendRequest(List<byte> pdu)
        {
            if (pdu == null || pdu.Count == 0)
                throw new ArgumentNullException(nameof(pdu), "PDU不能为空");
            Result<bool> connectState = ((Ethernet)CommunicationUnit).OpenAsync(1000).Result;

            if (!connectState.Status)
            {
                return new byte[0];
            }
            List<byte> bytesMBAP = new List<byte>();
            // 构建完整的Modbus TCP消息 (MBAP + PDU)
            byte[] transactionId = BitConverter.GetBytes((ushort)Interlocked.Increment(ref TransactionId));
            if (BitConverter.IsLittleEndian)  Array.Reverse(transactionId);
            bytesMBAP.AddRange(transactionId);

            byte[] protocolId = new byte[] { 0x00, 0x00 }; // Modbus协议ID
            bytesMBAP.AddRange(protocolId);

            byte[] length = BitConverter.GetBytes((ushort)(pdu.Count ));
            if (BitConverter.IsLittleEndian)    Array.Reverse(length);
            bytesMBAP.AddRange(length);

            //byte unitId = 0x01; // 通常为1 从站地址
            //bytesMBAP.Add(unitId);
            bytesMBAP.AddRange(pdu);
            //byte[] request = new byte[7+ pdu.Count];
            //Array.Copy(transactionId, 0, request, 0, 2);
            //Array.Copy(protocolId, 0, request, 2, 2);
            //Array.Copy(length, 0, request, 4, 2);
            //request[6] = unitId;
            //Array.Copy(pdu.ToArray(), 0, request, 6, pdu.Count);
            var repContent = ModbusLengthCalculator.ExtractDataFromRequest(ModbusProtocolType.TcpIp, bytesMBAP.ToArray());

             
            int functionCode = repContent.FunctionCode;
            int dataCount = repContent.DataCount;
            int receiveLen = ModbusLengthCalculator.CalculateNormalResponseLength(ModbusProtocolType.TcpIp, functionCode, dataCount);
            int errrorLen = ModbusLengthCalculator.CalculateExceptionResponseLength(ModbusProtocolType.TcpIp);
             
            var result = ((Ethernet)CommunicationUnit).SendAndReceiveAsync(bytesMBAP, receiveLen,errrorLen).Result;

            if (!result.Status)
                throw new InvalidOperationException($"通信失败: {result.Message}");

            List<byte> responseBuffer = result.Datas;

            if (responseBuffer.Count < 9) // 至少需要MBAP(6) + 单元ID(1) + 功能码(1) + 至少1字节数据
                throw new InvalidDataException("接收到的响应长度不足");

            // 提取PDU部分 (跳过MBAP头)
            byte[] responsePdu = new byte[responseBuffer.Count - 6];
            Array.Copy(responseBuffer.ToArray(), 6, responsePdu, 0, responseBuffer.Count - 6);

            return responsePdu;

        }


        //protected override byte[] SendRequest(List<byte> pdu)
        //{
        //    if (pdu == null || pdu.Count == 0)
        //        throw new ArgumentNullException(nameof(pdu), "PDU不能为空");

        //    using (TcpClient client = new TcpClient())
        //    {
        //        // 连接到Modbus TCP服务器
        //        try
        //        {
        //            // 假设IP地址和端口在构造函数或配置中设置
        //            client.Connect("127.0.0.1", 502);
        //        }
        //        catch (Exception ex)
        //        {
        //            throw new InvalidOperationException("无法连接到Modbus服务器", ex);
        //        }

        //        using (NetworkStream stream = client.GetStream())
        //        {
        //            // 构建完整的Modbus TCP消息 (MBAP + PDU)
        //            byte[] transactionId = BitConverter.GetBytes((ushort)Interlocked.Increment(ref _transactionId));
        //            if (BitConverter.IsLittleEndian)
        //                Array.Reverse(transactionId);

        //            byte[] protocolId = new byte[] { 0x00, 0x00 }; // Modbus协议ID
        //            byte[] length = BitConverter.GetBytes((ushort)(pdu.Count + 1));
        //            if (BitConverter.IsLittleEndian)
        //                Array.Reverse(length);

        //            byte unitId = 0x01; // 通常为1

        //            byte[] request = new byte[6 + pdu.Count];
        //            Array.Copy(transactionId, 0, request, 0, 2);
        //            Array.Copy(protocolId, 0, request, 2, 2);
        //            Array.Copy(length, 0, request, 4, 2);
        //            request[6] = unitId;
        //            Array.Copy(pdu.ToArray(), 0, request, 7, pdu.Count);

        //            // 发送请求
        //            stream.Write(request, 0, request.Length);

        //            // 接收响应
        //            byte[] buffer = new byte[1024];
        //            int bytesRead = stream.Read(buffer, 0, buffer.Length);

        //            if (bytesRead < 9) // 至少需要MBAP(6) + 单元ID(1) + 功能码(1) + 至少1字节数据
        //                throw new InvalidDataException("接收到的响应长度不足");

        //            // 提取PDU部分 (跳过MBAP头)
        //            byte[] responsePdu = new byte[bytesRead - 6];
        //            Array.Copy(buffer, 6, responsePdu, 0, bytesRead - 6);

        //            return responsePdu;
        //        }
        //    }
        //}

        // 计算预期的响应长度（包含MBAP头）

    }
}